package com.myself.ssoserver.service

import com.auth0.jwt.JWT
import com.auth0.jwt.algorithms.Algorithm
import com.auth0.jwt.interfaces.DecodedJWT
import com.fasterxml.jackson.databind.ObjectMapper
import com.myself.ssoserver.entity.User
import org.redisson.api.RedissonClient
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Value
import org.springframework.context.annotation.Lazy
import org.springframework.stereotype.Service
import java.util.*
import java.util.concurrent.TimeUnit

@Service
open class SessionService(
    private val redisson: RedissonClient
) {

    companion object {
        private const val TOKEN_PREFIX = "sso:token:"
        private const val USER_PREFIX = "user_tokens:"
        private const val EXPIRATION_MINUTES = 30L
    }

    @Value("\${auth0.jwt.secret:secret-key}")
    private val secretKey :String? = null

    open fun createSession(user: User, ip: String): String {

        val objectMapper = ObjectMapper()
        val userJson = objectMapper.writeValueAsString(user)

        val token = JWT.create()
            .withSubject(user.id.toString())
            .withClaim("ip", ip)
            .withClaim("user", userJson)
            .withIssuedAt(Date())
            .sign(Algorithm.HMAC256(secretKey))

        redisson.getBucket<Any>("$TOKEN_PREFIX$token").set(
            mapOf(
                "userId" to user.id,
                "username" to user.username,
                "ip" to ip
            ),
            EXPIRATION_MINUTES,
            TimeUnit.MINUTES
        )

        // 存储 token 到用户集合
        val userTokenKey = "$USER_PREFIX${user.id}"
        redisson.getSet<String>(userTokenKey).add(token)

        // 设置过期时间（与 token 相同）
        redisson.getSet<String>(userTokenKey).expire(EXPIRATION_MINUTES, TimeUnit.MINUTES)

        return token
    }


    open fun validateToken(token: String): Boolean {
        return try {
            JWT.require(Algorithm.HMAC256(secretKey)).build().verify(token)
            redisson.getBucket<Any>("$TOKEN_PREFIX$token")?.get() != null
        } catch (ex: Exception) {
            false
        }
    }

    open fun parseToken(token: String): DecodedJWT {
        val algorithm = Algorithm.HMAC256(secretKey)
        val verifier = JWT.require(algorithm).build()
        return verifier.verify(token) // 解析 Token
    }

    fun clearUserTokens(userId:Int) {
        val userTokenKey = "$USER_PREFIX:$userId"
        val tokens = redisson.getSet<String>(userTokenKey).readAll()

        tokens.forEach { token ->
            // 删除 token 存储
            redisson.getBucket<Any>("$TOKEN_PREFIX$token").delete()
        }
        // 删除用户 token 集合
        redisson.getSet<String>(userTokenKey).delete()
    }
}